﻿namespace HZY.Framework.Core.Filters;

/// <summary>
/// Api result returns wrapper
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ApiResultFilterAttribute(bool ignore = false) : Attribute, IAsyncResultFilter
{
    private bool Ignore { get; set; } = ignore;

    public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
    {
        if (Ignore)
        {
            // Continue execution in the pipeline
            await next.Invoke();
            return;
        }

        if (context.HttpContext.IsDownLoadFile())
        {
            // Continue execution in the pipeline
            await next.Invoke();
            return;
        }

        var routeValues = context.ActionDescriptor.RouteValues;
        var actionName = (routeValues["action"] ?? context.HttpContext.Request.Path).ToLower();

        // 判断接口名称，是否包含，create，update，delete，query，search 关键字，然后 提供不同的状态码
        var statusCode = HttpStatusCode.OK;
        if (actionName.Contains("create") || actionName.Contains("add") || actionName.Contains("insert"))
        {
            statusCode = HttpStatusCode.Created;
        }

        if (actionName.Contains("update") || actionName.Contains("edit") || actionName.Contains("save") ||
            actionName.Contains("modify"))
        {
            statusCode = HttpStatusCode.OK;
        }

        if (actionName.Contains("delete") || actionName.Contains("remove"))
        {
            statusCode = HttpStatusCode.OK;
        }

        if (actionName.Contains("query") || actionName.Contains("search") || actionName.Contains("list") ||
            actionName.Contains("find"))
        {
            statusCode = HttpStatusCode.OK;
        }

        if (context.Result is JsonResult jsonResult && jsonResult.Value is R)
        {
            // Continue execution in the pipeline
            await next.Invoke();
            return;
        }

        if (context.Result is ObjectResult result)
        {
            var r = context.HttpContext.ResultData(statusCode, result.Value);

            context.Result = new JsonResult(r);
        }
        else if (context.Result is ContentResult contentResult)
        {
            var r = context.HttpContext.ResultData(HttpStatusCode.OK, contentResult.Content);

            context.Result = new JsonResult(r);
        }
        else if (context.Result is EmptyResult)
        {
            var r = new NoContentResult();
            context.Result = new JsonResult(r);
        }

        // Continue execution in the pipeline
        await next.Invoke();
    }
}